package com.i360day.redis.constant;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;

import java.util.concurrent.TimeUnit;

/**
 * @description: 获取redisTemplate
 * @author: liju.z
 * @create: 2019-09-08 17:54
 **/
public class RedisContextHolder {

    private static RedisTemplate<String, Object> redisTemplate;

    private static ValueOperations<String, Object> valueOperations;

    public RedisContextHolder(RedisTemplate<String, Object> redisTemplate, ValueOperations<String, Object> valueOperations) {
        this.redisTemplate = redisTemplate;
        this.valueOperations = valueOperations;
    }

    public static RedisTemplate<String, Object> getRedisTempate() {
        return redisTemplate;
    }

    public static ValueOperations<String, Object> getValueOperations() {
        return valueOperations;
    }

    /**
     * JSON数据，转成Object
     */
    private static <T> T fromJson(Object json, Class<T> clazz) {
        if (json == null) return null;
        if (json instanceof String) {
            return (T) json.toString();
        } else {
            return JSON.parseObject(JSON.toJSONString(json), clazz);
        }
    }

    public static JSONObject getRightPop(String key, int timeout, TimeUnit timeUnit) {
        Object returnObj = getRedisTempate().opsForList().rightPop(key, timeout, timeUnit);
        if (returnObj == null) return new JSONObject();
        return fromJson(returnObj, JSONObject.class);
    }

    public static Object leftPop(String key) {
        return getRedisTempate().opsForList().leftPop(key);
    }

    public static void leftPush(String key, Object value) {
        getRedisTempate().opsForList().leftPush(key, value);
    }

    public static void rightPush(String key, Object value) {
        getRedisTempate().opsForList().rightPush(key, value);
    }

    /**
     * 删除缓存
     *
     * @param key 键
     * @author zmr
     */
    public static void delete(String key) {
        getRedisTempate().delete(key);
    }

    /**
     * 返回指定类型结果
     *
     * @param key   键
     * @param clazz 类型class
     * @return
     * @author zmr
     */
    public static <T> T get(String key, Class<T> clazz) {
        Object value = getValueOperations().get(key);
        return value == null ? null : fromJson(value, clazz);
    }

    /**
     * 插入缓存默认时间
     *
     * @param key   键
     * @param value 值
     * @author zmr
     */
    public static void set(String key, Object value) {
        getValueOperations().set(key, value);
    }

    /**
     * 插入缓存
     *
     * @param key    键
     * @param value  值
     * @param expire 过期时间(s)
     * @author zmr
     */
    public static void set(String key, Object value, long expire) {
        getValueOperations().set(key, value, expire, TimeUnit.SECONDS);
    }

    /**
     * <p> @Author liju.z <p>
     *
     * <p> @Description 设置key的过期时间 <p>
     *
     * <p> @Date  13:52 <p>
     *
     * <p> @Param [key, expire] <p>
     *
     * <p> @return [key, expire] <p>
     **/
    public static void setExpire(String key, long expire) {
        getRedisTempate().expire(key, expire, TimeUnit.SECONDS);
    }

    /**
     * <p> @Author liju.z <p>
     *
     * <p> @Description 组装队列key <p>
     *
     * <p> @Date  9:55 <p>
     *
     * <p> @Param [keys] <p>
     *
     * <p> @return [keys] <p>
     **/
    public static String getQueueKey(String... keys) {
        StringBuilder builder = new StringBuilder("redis:queue:key");
        for (String key : keys) {
            builder.append("_").append(key);
        }
        return builder.toString();
    }

    public static String getQueueLeftKey(String... keys) {
        return getQueueKey(keys) + "_left";
    }

    public static String getQueueRightKey(String... keys) {
        return getQueueKey(keys) + "_right";
    }

    /**
     * <p> @Author liju.z <p>
     *
     * <p> @Description 获取redis缓存key <p>
     *
     * <p> @Date  11:28 <p>
     *
     * <p> @Param [keys] <p>
     *
     * <p> @return [keys] <p>
     **/
    public static String getRedisKey(String... keys) {
        StringBuilder builder = new StringBuilder("redis:cache:key");
        for (String key : keys) {
            builder.append("_").append(key);
        }
        return builder.toString();
    }
}
